"""
Основной исполняемый модуль проекта кластеризации и маршрутизации сети. 
Выполняет функции генерации объектов в 3D пространстве, кластеризации и анализа маршрутов связи.
Сохраняет сет данных для анализа, выводит статистику в терминал и визуализирует на 3D графике.
"""
from swarm_network import charts
from swarm_network import clusters
from swarm_network import data
from swarm_network import graph

# Чтение конфигурации и установка параметров генерации
config = data.read_config('config.yaml')
objects_type = config['objects_type']
filename_prefix = config['filename_prefix']
data_directory = config['data_directory']
deviation_x_y = config['deviation_x_y']
deviation_z = config['deviation_z']
base_point = config['base_point']
count_clusters = config['count_clusters']
base_connections = config['base_connections']
leaders_connections = config['leaders_connections']
objects_paths = config['objects_paths']
num_points = config['num_points']
square_side = config['square_side']
rows = config['rows']
step = config['step']
attitude = config['attitude']
# Ручное конфигурирование и переопределение параметров
SHOW_CLUSTERS = True

square_side = 100000
num_points = 125
objects_type = 'grid'
base_point = [50000, 50000, 0]
base_connections = 3
leaders_connections = 4
count_clusters = 21
attitude = 1000
objects_paths = False

# Генерация объектов исходя из типа распределения
if objects_type == 'grid': # Сетка
    df = data.generate_points_grid(num_points, square_side,
                                       attitude, deviation_x_y, deviation_z)
    filename = f"{filename_prefix}-{objects_type}-{num_points}-side{square_side}-z{attitude}"
elif objects_type == 'rows':  # Ряды
    df = data.generate_points_rows(num_points, rows, step,
                                       attitude, deviation_x_y, deviation_z)
    filename = f"{filename_prefix}-{objects_type}-{num_points}-rows{rows}-step{step}-z{attitude}"
else:  # Произвольный
    df = data.generate_points_random(num_points, square_side, attitude)
    filename = f"{filename_prefix}-{objects_type}-{num_points}-side{square_side}-z{attitude}"

# Сохранение результата в файл
print(f'Данные успешно сгенерированы и сохранены в файл {filename}')
data.save_data(df, data_directory, filename)

df_objects = df.copy()
# Кластеризация
df_objects, df_clusters = clusters.clustering(df_objects, count_clusters, base_point)

# Выбор ближайших к базовой станции
df_objects, df_clusters = clusters.set_base_connectors(df_objects, df_clusters, base_connections)

# Создание графа сети
Graph = graph.generate_graph(df_objects, df_clusters, base_point)

# Фильтрация графа сети по количество коннектов между кластерами и базовой станцией
filtered_G = graph.filter_connections(Graph, base_connections, leaders_connections)

# Маршрутизация сети и поиск кратчашего пути
df_objects = graph.short_paths(filtered_G, df_objects)

# Сохранение каналов связи в дата сет
df_clusters, df_routes = graph.routing_stat(filtered_G, df_clusters)

# Вывод статистики по графам сети в терминал
graph.print_stat(filtered_G)

# Вывод статистики по кластерам и объектам в терминал
clusters.print_stat(df_objects)

# Сохранение результатов в файл
result_filename_objects = f'{filename}-results-objects'
data.save_data(df_objects, data_directory, result_filename_objects)

## Каналы связи
result_filename_clusters = f'{filename}-results-clusters'
data.save_data(df_clusters, data_directory, result_filename_clusters)

## Каналы связи
result_filename_routes = f'{filename}-results-routes'
data.save_data(df_routes, data_directory, result_filename_routes)

# Отображение путей из конфигурации
charts.print_short_paths(filtered_G, df_objects, df_clusters, objects_paths, SHOW_CLUSTERS)
